/**
 * 单个请求生命周期
 *
 * 参考：https://blog.csdn.net/joye123/article/details/82115562
 *
 * 概念：
 * 1.DNS解析是请求DNS（Domain Name System）服务器，将域名解析成ip的过程
 *
 * 注意：
 * 1.当连接被重用时，connectStart/connectEnd不会被调用。
 */

const keys = [
  'requestId',
  'url',
  'callStart',
  'dnsStart',
  'dnsEnd',
  'connectStart',
  'secureConnectStart',
  'secureConnectEnd',
  'connectEnd',
  'connectFailed',
  'connectionAcquired',
  'connectionReleased',
  'requestHeadersStart',
  'requestHeadersEnd',
  'requestBodyStart',
  'requestBodyEnd',
  'responseHeadersStart',
  'responseHeadersEnd',
  'responseBodyStart',
  'responseBodyEnd',
  'responseFailed',
  'callEnd',
  'callFailed'
];

export interface RequestInfo {
  requestId: number; // 请求序号
  url: string; // 请求；链接
  callStart?: number; // 请求开始 - 当一个请求被同步执行或被添加异步队列中时
  dnsStart?: number; // dns解析开始
  dnsEnd?: number; // dns解析结束
  connectStart?: number; // 连接开始
  secureConnectStart?: number; // TLS安全连接结束
  secureConnectEnd?: number; // TLS安全连接开始
  connectEnd?: number; // 连接结束
  connectFailed?: number; // 连接失败 - 无论是Socket连接失败，还是TSL/SSL握手失败，都会回调
  connectionAcquired?: number; // 连接绑定 - 打开输入输出流
  connectionReleased?: number; // 连接释放 - 用完释放流
  requestHeadersStart?: number; // 请求数据发送 - 发送请求头
  requestHeadersEnd?: number;
  requestBodyStart?: number; // 请求数据发送 - 发送请求体
  requestBodyEnd?: number;
  responseHeadersStart?: number; // 响应数据读取 - 读取响应头
  responseHeadersEnd?: number;
  responseBodyStart?: number; // 响应数据读取 - 读取响应体
  responseBodyEnd?: number;
  responseFailed?: number;
  callEnd?: number; // 请求结束 - 1.关闭流时；2.释放连接时
  callFailed?: number; // 请求异常 - 1.请求执行的过程中发生异常时；2.请求结束后，关闭输入流时产生异常时
}

let requests: { [key: string]: any }[] = [];

export const setRequestInfo = (request: { [key: string]: any }): void => {
  const res: { [key: string]: any } = {};
  keys.forEach((item): void => {
    if (request[item]) {
      res[item] = request[item];
    }
  });
  requests = [...requests, res];
};

export const getRequestInfoWithId = (
  id: number
): { [key: string]: any } | null => {
  const request = requests.find((item): boolean => item.requestId === id);
  if (request) {
    return request;
  }
  return null;
};
